package com.sam.stockvalue.service.impl;

import com.sam.stockvalue.dao.TStockConfigDao;
import com.sam.stockvalue.dao.TStockHolderDao;
import com.sam.stockvalue.dao.TStockHolderRelaDao;
import com.sam.stockvalue.dao.TStockValueDetailDao;
import com.sam.stockvalue.model.TStockConfig;
import com.sam.stockvalue.model.TStockHolder;
import com.sam.stockvalue.model.TStockHolderRela;
import com.sam.stockvalue.model.TStockValueDetail;
import com.sam.stockvalue.service.MailSendService;
import com.sam.stockvalue.service.ProcessSVService;
import com.sam.stockvalue.service.StockSpiderService;
import com.sam.stockvalue.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @description:
 * @author:
 */
@Service
public class ProcessSVServiceImpl implements ProcessSVService {

    Logger logger = LoggerFactory.getLogger(ProcessSVServiceImpl.class);

    @Autowired
    TStockConfigDao stockConfigDao;

    @Autowired
    TStockHolderDao stockHolderDao;

    @Autowired
    TStockValueDetailDao stockValueDetailDao;

    @Autowired
    TStockHolderRelaDao stockHolderRelaDao;

    @Autowired
    MailSendService mailSendService;

    @Autowired
    StockSpiderService spiderService;

    private ThreadLocal<HashMap<String, TStockConfig>> hashMapThreadLocal = new ThreadLocal<>();

    @Override
    public void doBusiness() {

        logger.info("### 当前处理线程名称[{}]", Thread.currentThread().getName());

        HashMap<String, TStockConfig> configMap = hashMapThreadLocal.get();
        if(configMap == null) {
            configMap = new HashMap<>();
            hashMapThreadLocal.set(configMap);
        }
        //1.获取股票配置信息
        List<TStockConfig> allStockConfig = stockConfigDao.getAllStockConfig();
        for (TStockConfig tStockConfig : allStockConfig) {

            //爬取最新股价并赋值
            spiderService.doSpiderStock(tStockConfig);
            stockConfigDao.updateByPrimaryKeySelective(tStockConfig);//保存最新股价

            if(!configMap.containsKey(tStockConfig.getCode())){
                configMap.put(tStockConfig.getCode(), tStockConfig);
            }
        }

        //关闭webdriver并清理
        spiderService.clearThreadLocal();

        //2.获取持有人
        List<TStockHolder> allStockHolder = stockHolderDao.getAllStockHolder();
        for(TStockHolder stockHolder: allStockHolder) {
            //3.以持有人为单位进行处理
            this.processStockHolderRela(stockHolder);
        }

        //4.清空缓存，下次再跑批时重新获取
        configMap.clear();

    }

    /**
     * 以持有人为单位进行账户处理
     * @param stockHolder
     */
    private void processStockHolderRela(TStockHolder stockHolder) {
        TStockHolderRela stockHolderRela = new TStockHolderRela();
        stockHolderRela.setHolderId(stockHolder.getHolderId());
        List<TStockHolderRela> stockHolderRelas = stockHolderRelaDao.getStockHolerRela(stockHolderRela);
        BigDecimal holderStockValue = BigDecimal.ZERO;

        TStockValueDetail stockValueDetail = new TStockValueDetail();
        stockValueDetail.setHolderId(stockHolder.getHolderId());
        stockValueDetail.setExchangeDate(new Date());
        stockValueDetailDao.deleteStockValueDetail(stockValueDetail);

        for (TStockHolderRela holderRela: stockHolderRelas) {

            TStockConfig tStockConfig = hashMapThreadLocal.get().get(holderRela.getStockCode());
            BigDecimal stockValue = tStockConfig.getCurPrice().multiply(new BigDecimal(holderRela.getStockNums()));
            holderStockValue = holderStockValue.add(stockValue);
            this.processStockDetails(holderRela, stockValue);
        }

        processMail(stockHolder, holderStockValue);
    }

    /**
     * 插入账户变动明细表
     * @param holderRela
     * @param stockValue
     */
    private void processStockDetails(TStockHolderRela holderRela, BigDecimal stockValue) {

        TStockConfig tStockConfig = hashMapThreadLocal.get().get(holderRela.getStockCode());

        TStockValueDetail stockValueDetail = new TStockValueDetail();
        stockValueDetail.setHolderId(holderRela.getHolderId());
        stockValueDetail.setExchangeDate(new Date());
        stockValueDetail.setStockCode(holderRela.getStockCode());
        stockValueDetail.setStockValue(stockValue);
        stockValueDetail.setStockNums(holderRela.getStockNums());
        stockValueDetail.setStockPrice(tStockConfig.getCurPrice());
        stockValueDetailDao.insertSelective(stockValueDetail);
    }

    /**
     * 按持有人发送邮件
     * @param stockHolder
     */
    private void processMail(TStockHolder stockHolder, BigDecimal holderStockValue){

        TStockValueDetail stockValueDetail = new TStockValueDetail();
        stockValueDetail.setHolderId(stockHolder.getHolderId());
        stockValueDetail.setExchangeDate(new Date());
        List<TStockValueDetail> detailList = stockValueDetailDao.getStockValueDetail(stockValueDetail);

        BigDecimal sumValue = BigDecimal.ZERO;

        StringBuilder builder = new StringBuilder("<html>\n<body>\n");
        builder.append("Dear, ");
        builder.append(stockHolder.getHolderName());
        builder.append("<table border='1px'><th>编码</th><th>名称</th><th>股本</th><th>最新价</th><th>总金额</th><th>仓位</th>");
        for (TStockValueDetail detail : detailList) {
            TStockConfig tStockConfig = hashMapThreadLocal.get().get(detail.getStockCode());
            builder.append("<tr><td border='1px'>");
            builder.append(detail.getStockCode());
            builder.append("</td><td border='1px'>");
            builder.append(tStockConfig.getName());
            builder.append("</td><td border='1px'>");
            builder.append(detail.getStockNums());
            builder.append("</td><td border='1px'>");
            builder.append(detail.getStockPrice());
            builder.append("</td><td border='1px'>");
            if(detail.getStockValue().compareTo(detail.getStockPrice().multiply(new BigDecimal(detail.getStockNums()))) == 0) {
                builder.append(detail.getStockValue());
            } else {
                builder.append("<font color='red'>");
                builder.append(detail.getStockValue());
                builder.append("</font>");
            }
            builder.append("</td><td border='1px'>");
            builder.append(detail.getStockValue().divide(holderStockValue, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
            builder.append("</td></tr>");

            sumValue = sumValue.add(detail.getStockValue());
        }
        builder.append("<tr border='1px'><td>总计：</td><td colspan='5' border='1px'>");
        builder.append(holderStockValue);
        builder.append("</td></tr>");
        builder.append("</table>");


        stockValueDetail = new TStockValueDetail();
        stockValueDetail.setHolderId(stockHolder.getHolderId());
        Date lastDay = DateUtils.addDays(new Date(), -1);
        stockValueDetail.setExchangeDate(lastDay);
        detailList = stockValueDetailDao.getStockValueDetail(stockValueDetail);
        if(!CollectionUtils.isEmpty(detailList)) {
            BigDecimal lastValue = BigDecimal.ZERO;
            for (TStockValueDetail svd : detailList) {
                lastValue = lastValue.add(svd.getStockValue());
            }

            builder.append("<br>同前一日比："+holderStockValue.subtract(lastValue).multiply(BigDecimal.TEN).multiply(BigDecimal.TEN).divide(lastValue, 2, RoundingMode.HALF_UP)+"%");
        }
        if(sumValue.compareTo(holderStockValue) != 0) {
            builder.append("<br><font color='red'>数据核对有误，请留意！</font>");
        }

        builder.append("</body>\n</html>");
        mailSendService.sendMimeMail(stockHolder.getEmail(), "今日市值提醒", builder.toString());
    }

}
